<?php
declare (strict_types=1);

namespace app\course\logic\comment;

use app\common\exception\LogicException;
use app\common\logic\Common;
use app\course\event\subscribes\comment\Comment as CommentEvent;
use app\course\model\base\{Course};
use app\course\model\comment\{Comment as CommentModel, CommentLike, CommentReply, CommentReplyLike};
use app\user\logic\user\Credit;
use think\facade\Event;

/**
 * 点评接口类
 */
class Comment extends CommentModel
{
    /**
     * 我的点评
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-04
     */
    public function myCommentsList()
    {
        return $this
            ->scope('mid')
            ->with(['course_title'])
            ->paginate($this->getListRows());
    }

    /**
     * 获取课程的点评信息
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-13
     */
    public function getList($course_id)
    {
        $empty     = new \ArrayObject();
        $withCount = [
            'commentReply' => 'reply_count',
            'commentLike'  => 'like_count',
            'liked'        => 'like',
        ];

        $list = $this->withCount($withCount)
            ->where('course_id', $course_id)
            ->whereNull('delete_time')
            ->order('id DESC')
            ->paginate($this->getListRows());

        // 当前用户是否点评
        $mine = $this
            ->withCount($withCount)
            ->where([
                'course_id' => $course_id,
                'user_id'   => request()->mid,
            ])
            ->findOrEmpty();

        $did = $mine->isEmpty() == false;
        $did && $this->parseUser($mine);

        $comments['has_comment'] = $did;
        $comments['my_comment']  = $did ? $mine : $empty;

        if ($list->isEmpty()) {
            $comments['star'] = 5;
            $comments['list'] = $empty;
        } else {
            // 解析用户
            foreach ($list as $comment) {
                $this->parseUser($comment);
            }
            // 当前课程平均得分
            $star = $this->where(['course_id' => $course_id])->avg('star');
            // 计算值
            $comments['star'] = round(ceil($star) / 20, 1);
            $comments['list'] = $list;
        }

        return $comments;
    }

    /* 解析用户信息 */
    protected function parseUser($obj)
    {
        $obj->user = $obj->user()->field('id,nick_name,avatar')->find();
    }

    /**
     * 添加点评
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-13
     */
    public function addComment($course_id, $data)
    {
        // 验证数据
        $this->getValidate()->scene('add')->failException()->check($data);
        // 内容过滤
        $data['content'] = app(Common::class)->filterSensitive($data['content'], $course_id, 'comment');
        // 参数
        $mid = request()->mid;
        // 当前用户是否点评
        $comment = $this->where(['course_id' => $course_id, 'user_id' => $mid])->findOrEmpty();

        if ($comment->isEmpty()) {
            // 添加数据
            $data['user_id']   = $mid;
            $data['course_id'] = $course_id;
            $data['star']      = $data['star'] * 20;

            if (!$this->data($data, true)->save()) throw new LogicException('添加失败');

            $return = $this;

            $course = app(Course::class)->field('title,comment_credit credit')->findOrEmpty($course_id);
            if (!$course->isEmpty() && $course->credit) {
                /* 参数说明【消费用户ID、流水类型、积分变动数额、消费关联表、关联表ID、消费备注】 */
                app(Credit::class)->increaseUserCredit($mid, 4, $course->credit, 'course_comment', $return->id, '评论课程《' . $course->title . '》获得积分');
            }
        } else {
            $comment->star    = $data['star'] * 20;
            $comment->content = $data['content'];
            $comment->save();
            $return = $this->find($comment->id);
        }

        // 事件处理课程点评
        Event::subscribe(CommentEvent::class);
        Event::trigger('CommentScore', $return);

        return $return;
    }

    /**
     * delComment
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 23/09/25
     *
     * @param $id
     */
    public function delComment($id)
    {
        $data = $this->findOrEmpty($id);
        if ($data->user_id != request()->mid) throw new LogicException('无法删除他人的评论');
        if(!$data->delete()) throw new LogicException('删除失败');
    }

    /**
     * 评论点赞状态
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-16
     *
     * @param    [type]                      $data [description]
     * @return   [type]                            [description]
     */
    public function changeCommentLikeStatus($id, $data)
    {
        // 验证数据
        $this->getValidate()->scene('like')->failException()->check($data);
        // 参数
        $mid = request()->mid;
        // 获取对象模型
        $data['course_comment_id'] = $id;
        $data['like_user_id']      = $mid;

        $model = app(CommentLike::class);
        $like  = $model
            ->withTrashed()
            ->where('course_comment_id', $id)
            ->where('like_user_id', $mid)
            ->findOrEmpty();

        return $this->updateStatus($model, $like, $data);
    }

    /**
     * 评论回复点赞状态
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-16
     *
     * @param    [type]                      $data [description]
     * @return   [type]                            [description]
     */
    public function changeCommentReplyLikeStatus($id, $data)
    {
        // 验证数据
        $this->getValidate()->scene('like')->failException()->check($data);

        // 参数
        $mid = request()->mid;

        // 获取对象模型
        $data['course_comment_reply_id'] = $id;
        $data['like_user_id']            = $mid;

        $model = app(CommentReplyLike::class);
        $like  = $model
            ->withTrashed()
            ->where('course_comment_reply_id', $id)
            ->where('like_user_id', $mid)
            ->findOrEmpty();

        return $this->updateStatus($model, $like, $data);
    }

    // 更新点赞状态
    public function updateStatus($model, $like, $data)
    {
        if ($like->isEmpty()) {
            // 不存在数据且status为1，添加数据
            if (!$data['status'] == 1) throw new LogicException('暂未点赞');

            $like = $model::create($data);
            if ($like->isEmpty()) throw new LogicException('点赞失败');
        } else {
            // 存在数据根据status修改数据
            if ($data['status'] == 1) {
                $like->restore();
                $like = $model->find($like->id);
            } else {
                $like->delete();
            }
        }

        return $like;
    }

    /**
     * 获取点评的评论信息
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-13
     */
    public function getReply($comment_id)
    {
        $comment = app(Comment::class)
            ->withCount([
                'commentReply' => 'reply_count',
                'commentLike'  => 'like_count',
                'liked'        => 'like',
            ])
            ->findOrFail($comment_id);
        $this->parseUser($comment);

        $return['comment']      = $comment;
        $return['commentReply'] = $comment
            ->commentReply()
            ->with(['reply_user'])
            ->withCount(['ReplyLike' => 'like_count', 'liked' => 'like'])
            ->paginate($this->getListRows());

        if (!$return['commentReply']->isEmpty()) {
            foreach ($return['commentReply'] as $reply) {
                // 当前评论用户
                $this->parseUser($reply);
            }
        }

        return $return;
    }

    /**
     * 添加评论回复
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-04-13
     */
    public function addReply($comment_id, $data)
    {
        // 验证数据
        $this->getValidate()->scene('addReply')->failException()->check($data);
        // 定义参数
        $mid                       = request()->mid;
        $reply_mod                 = app(CommentReply::class);
        $data['user_id']           = $mid;
        $data['course_comment_id'] = $comment_id;
        // 内容过滤
        $data['content'] = app(Common::class)->filterSensitive($data['content'], $comment_id, 'comment_reply');

        // 不能回复自己
        if ($data['reply_user_id'] == $mid) throw new LogicException('不能@自己回复');

        $reply = $reply_mod::create($data);

        if ($reply->isEmpty()) throw new LogicException('添加失败');

        $reply       = $reply_mod->with(['reply_user'])->findOrEmpty($reply->id);
        $reply->like = 0;

        // 当前评论用户
        $this->parseUser($reply);

        // 事务处理消息
        $param['send_user_id'] = $mid;
        // 有@用户时：写入@用户ID；无@用户时：写入点评课程的用户ID
        $param['recive_user_id'] = $data['reply_user_id'] ?: ($this->where('id', $comment_id)->value('user_id') ?: 0);
        $param['notify_data_id'] = $comment_id;
        $param['content']        = $data['content'];

        Event::subscribe(CommentEvent::class);
        Event::trigger('CommentNotify', $param);

        return $reply;
    }

    /**
     * delCommentReply
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 23/09/25
     *
     * @param $id
     */
    public function delCommentReply($id)
    {
        $data = app(CommentReply::class)->findOrEmpty($id);
        if ($data->user_id != request()->mid) throw new LogicException('无法删除他人的评论');
        if(!$data->delete()) throw new LogicException('删除失败');
    }
}
